<?php

namespace app\admin\controller;

use addons\epay\library\Service;
use app\admin\model\film\Info as FilmInfo;
use app\admin\model\Hall;
use app\admin\model\Order as OrderModel;
use app\admin\model\Schedule as ScheduleModel;
use app\admin\model\user\Coupons as UserCoupons;
use app\common\model\User;
use app\admin\model\user\Level;
use app\common\controller\Backend;
use app\common\model\MoneyLog;
use app\common\model\OrderTicket;
use app\common\service\Order as OrderService;
use PhpOffice\PhpWord\TemplateProcessor;
//use PHPQRCode\QRcode;
use Endroid\QrCode\QrCode;
use think\Db;
use think\exception\DbException;
use think\Log;
use think\Queue;
use think\response\Json;

/**
 * 订单
 *
 * @icon fa fa-circle-o
 */
class Order extends Backend
{

    /**
     * Order模型对象
     * @var \app\admin\model\Order
     */
    protected $noNeedLogin = ['test'];
    protected $noNeedRight = ['*'];
    protected $relationSearch = true;
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\Order;
        $this->view->assign("payTypeList", $this->model->getPayTypeList());
        $this->view->assign("statusList", $this->model->getStatusList());
        $this->view->assign("refundStatusList", $this->model->getRefundStatusList());
    }



    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */

    /**
     * 查看
     *
     * @return string|Json
     * @throws \think\Exception
     * @throws DbException
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if (false === $this->request->isAjax()) {
            return $this->view->fetch();
        }
        //如果发送的来源是 Selectpage，则转发到 Selectpage
        if ($this->request->request('keyField')) {
            return $this->selectpage();
        }
        [$where, $sort, $order, $offset, $limit] = $this->buildparams();
        $list = $this->model
            ->with(['schedule','hall','film','user'])
            ->where($where)
            ->order($sort, $order)
            ->paginate($limit);
        if($list){
            foreach ($list as $key=>&$value){
                $select_seat_str = '';

                $ticket_seat_name_arr = OrderTicket::where(['order_id'=>$value['id']])->column('seat_name');
//                var_dump($ticket_seat_name_arr);
                foreach ($ticket_seat_name_arr as $k=>$v)
                {
                    $select_seat_str .= $v.' ';
                }
//                var_dump($select_seat_str);
                $value['select_seat_str'] = $select_seat_str;
            }
        }
        $result = ['total' => $list->total(), 'rows' => $list->items()];
        return json($result);
    }

    /**
     * 确认订单
     */
    public function confirm()
    {
        $schedule_id = $this->request->post('schedule_id',0);
        $select_seat = json_decode($this->request->param('select_seat'),true);
        $pay_type = $this->request->post('pay_type','money');
        $user_mobile = $this->request->post('mobile','');
        $user = User::get(['mobile'=>$user_mobile]);

        $info = ScheduleModel::where(['id'=>$schedule_id,'status'=>1])->find();
        if (!$info)$this->result('',0,'场次不存在','json');
        if (!$select_seat) $this->result('',0,'请先选座','json');
        if(!$user) $this->result('',0,'用户不存在','json');

        $data['user_level'] = $user['level'];
        $data['discount'] = 1;
        if ($pay_type == 'money' && $data['user_level']>0){
            $level = Level::where(['level'=>$user['level']])->find();
            $data['discount'] = $level['discount'];
        }

        $film = FilmInfo::where(['id'=>$info['film_info_id']])->field('id,name,image,duration,performer,category_ids')->find();
        $hall = Hall::where(['id'=>$info['hall_id']])->find();
        $hall['seat_data'] = json_decode($hall['seat_data'],true);
        $data['cinema_name'] = config('site.cinema_name');
        $data['cinema_address'] = config('site.cinema_address');
        $select_seat_str = '';
        $total_amount = 0;

        foreach ($select_seat as $key=>$value)
        {
//            dump($value);
            $has_ticket = OrderTicket::where(['schedule_id'=>$schedule_id,'x_coord'=>$value['XCoord'],'y_coord'=>$value['YCoord']])->whereIn('status',[0,1,2])->find();
            if ($has_ticket){
                $this->error('座位已被选请重新选择');
            }
//            $seat_data = $hall['seat_data'][$value['XCoord']][$value['YCoord']];
            $select_seat_str .= $value['RowNum'].'排'.$value['ColumnNum'].'座 ';
            if ($value['level']=='normal')$total_amount += $info['seat_normal_price'];
            if ($value['level']=='comfortable')$total_amount += $info['seat_comfortable_price'];

        }
        $after_discount_fee = bcMath($total_amount,$data['discount'],'*');

        if($pay_type == 'money'){
            $user_money = $user['money'];
            if ($user_money < $after_discount_fee){
                $this->result('',0,'该用户余额不足，余额剩余：'.$user_money.'元','json');
            }
        }

        //创建订单信息
        // 启动事务
        Db::startTrans();
        try{
            $now = time();
            $expired = 300;
            $OrderModel = new OrderModel();
            $order_sn = build_order_no();
            $OrderModel->sn = $order_sn;
            $OrderModel->user_id = $user['id'];
            $OrderModel->user_level = $user['level'];
            $OrderModel->schedule_id = $info['id'];
            $OrderModel->hall_id = $info['hall_id'];
            $OrderModel->film_info_id = $info['film_info_id'];
            $OrderModel->cinema_name = $data['cinema_name'];
            $OrderModel->cinema_address = $data['cinema_address'];
            $OrderModel->total_amount = $total_amount;
            $OrderModel->total_fee = $after_discount_fee;
            $OrderModel->discount = $data['discount'];
            $OrderModel->after_discount_fee = $after_discount_fee;
            $OrderModel->coupon_id = 0;
            $OrderModel->coupon_fee = 0;
            $OrderModel->expired = $now+$expired;
            $OrderModel->qrcode_path = $this->scerweima($order_sn);
            $OrderModel->pay_type = $pay_type == 'money' ? 'system' : 'cash';
            $OrderModel->pay_time = $now;
            $OrderModel->status = 1;
            $OrderModel->save();
            $order_id = $OrderModel->id;
            $order_ticket_arr = [];
            foreach ($select_seat as $key=>$value)
            {
//                Log::info("测试====================");
//                Log::info($value);
//                $seat_data = $hall['seat_data'][$value['XCoord']][$value['YCoord']];
                if ($value['level']=='normal')$seat_price = $info['seat_normal_price'];
                if ($value['level']=='comfortable')$seat_price = $info['seat_comfortable_price'];
                $qrcode = $order_sn.'_'.$value['XCoord'].'_'.$value['YCoord'];
                $qrcode_path = $this->scerweima($qrcode);
                $ticket_data = [
                    'order_id'=>$order_id,
                    'user_id'=>$user['id'],
                    'schedule_id'=>$schedule_id,
                    'film_info_id'=>$info['film_info_id'],
                    'hall_id'=>$info['hall_id'],
                    'seat_price'=>$seat_price,
                    'seat_type'=>$value['level'],
                    'x_coord'=>$value['XCoord'],
                    'y_coord'=>$value['YCoord'],
                    'row_num'=>$value['RowNum'],
                    'column_num'=>$value['ColumnNum'],
                    'qrcode_path'=>$qrcode_path,
                    'status'=>1,
                    'createtime'=>$now,
                    'updatetime'=>$now
                ];
                array_push($order_ticket_arr,$ticket_data);
            }

//            foreach ($select_seat as $key=>$value)
//            {
////                $select_seat_str .= $value['XCoord'].'排'.$value['YCoord'].'列 ';
//                $seat_data = json_decode($hall['seat_data'],true);
////                Log::info('查到的数据：');
////                Log::info($seat_data);
//                Log::info('查到的数据：');
//                Log::info($seat_data[$value['XCoord']][$value['YCoord']]);
//                $seat_data[$value['XCoord']][$value['YCoord']]['status'] = 2;
//                $hall->save(['seat_data'=>json_encode($seat_data)]);
//            }

            $OrderTicketModel = new OrderTicket();
            $OrderTicketModel->saveAll($order_ticket_arr);

            if($pay_type == 'money' && $user) {
                $user->money(-$after_discount_fee, $user['id'],'订单:'.$OrderModel->sn.'后台购票');
//                MoneyLog::create(['user_id' => $user['id'], 'money' => $after_discount_fee, 'before' => $before, 'after' => $after, 'memo' => '订单:'.$order_id.'后台购票']);
            }
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            Log::error('确认订单系统错误:'.$e->getMessage());
//            Log::write('确认订单系统错误:'.$e->getMessage(),'error',true);
            $this->result('',0,'系统错误','json');
        }
        //创建订单成功生成到期取消延迟队列
//        Queue::later($expired, 'app\job\CancelorderJob', $order_id, 'cancelorder_queue');   // 取消订单延迟队列
        $data['hall_name'] = $hall['name'];
        $data['film_name'] = $film['name'];
        $data['film_image'] = compatImage($film['image']);
        $data['schedule_des'] = $info['des'];
        $data['schedule_date'] = $info['date'];
        $data['schedule_start_time'] = $info['start_time'];
        $data['schedule_end_time'] = $info['end_time'];
        $data['order_id'] = $order_id;
        $data['total_fee'] = $OrderModel->total_fee;
        $data['expired'] = $expired;
        $data['select_seat_str'] = $select_seat_str;


        $this->result($data,1,'购买成功','json');
    }


    /*
     * 打印小票
     * */
    public function ticket()
    {
        $param = $this->request->param();
        $order_info = $this->model->where('id',$param['id'])->find();
        $hall = Hall::where(['id'=>$order_info['hall_id']])->find();
        $film_info = FilmInfo::where(['id'=>$order_info['film_info_id']])->find();
        $schedules = ScheduleModel::where(['id'=>$order_info['schedule_id']])->find();

        $ticket_list = OrderTicket::where(['order_id'=>$order_info['id'],'status'=>1])->select();
        $ticket_list_arr = [];
        foreach ($ticket_list as $key=>$value)
        {
            $ticket_info['sn'] = $order_info['sn'];
            $ticket_info['hall_name'] = $hall['name'];
            $ticket_info['film_name'] = $film_info['name'];
            $ticket_info['start_date'] = $schedules['date'];
            $ticket_info['start_time'] = $schedules['start_time'];
            $ticket_info['seat_text'] =  ($value['row_num']).'排'.($value['column_num']).'座 ';
            $ticket_info['seat_price'] =  $value['seat_price'];
            $seat_type = $value['seat_type']=='normal'?'普通座':'舒适座';
            $ticket_info['seat_type'] =  $seat_type;
            $ticket_info['docx_name'] =$order_info['sn'].'_'.($value['row_num']).'_'.($value['column_num']);
            $ticket_info['ticket_path'] = $this->setContractContentWorld($ticket_info);
            array_push($ticket_list_arr,$ticket_info);
        }
//        halt($ticket_list_arr);
        $ticket_list_arr = $ticket_list_arr[0];
        return $this->view->fetch('',['order_info'=>$order_info,'ticket_list'=>$ticket_list_arr]);
    }

    public function update_order_status()
    {
        $order_id = $this->request->param('order_id',0);

        $order_info = $this->model->where('id',$order_id)->find();
        if($order_info['status']=='1')
        {
            $this->model->where('id',$order_info['id'])->setField('status','2');
            OrderTicket::where(['status'=>1,'order_id'=>$order_id])->update(['status'=>2]);
        }
    }

    /**
     * 生成订单合同内容world文件
     */
    public function setContractContentWorld($params)
    {

        $tmp = new TemplateProcessor('ticket_template.docx');

        $tmp->setValue('sn',$params['sn']);
        $tmp->setValue('hall_name',$params['hall_name']);
        $tmp->setValue('film_name',$params['film_name']);
        $tmp->setValue('start_date',$params['start_date']);
        $tmp->setValue('start_time',$params['start_time']);
        $tmp->setValue('seat_text',$params['seat_text']);
        $tmp->setValue('seat_price',$params['seat_price']);
        $tmp->setValue('seat_type',$params['seat_type']);

        $date = date('Ymd');
        $dir = '/uploads/ticket/'.$date;
        if(!is_dir($dir)){
            @mkdir('.'.$dir,0777);
        }

        $filename = $dir.'/'.$params['docx_name'].'.docx';
//        var_dump($filename);
        $tmp->saveAs('.'.$filename);//另存为
//        return $res;
        return compatImage($filename);
//        return ['full_path'=>compatImage($filename),'relative_path'=>$filename];
    }

    //生成二维码
    //2. 在生成的二维码中加上logo(生成图片文件)
    public function scerweima($text){

        $pathname = APP_PATH . '/../public/uploads/qrcode/';
        if(!is_dir($pathname)) { //若目录不存在则创建之
            mkdir($pathname,0777,true);
        }

        $errorCorrectionLevel = 'H';  //容错级别
        $matrixPointSize = 10;      //生成图片大小
        //生成二维码图片
        $abc = $text.'.png';
        $filename = $pathname.$abc;

        if (file_exists($filename)){
            return request()->domain().'/uploads/qrcode/'.$abc;
        }
        $url = request()->domain() ."?no=" . $text;
        \PHPQRCode\QRcode::png($text,$filename , $errorCorrectionLevel, $matrixPointSize, 2);
        return request()->domain().'/uploads/qrcode/'.$abc;
    }

    /*
     * 订单退款
     * */
    public function refund()
    {
        $order_id = $this->request->param('order_id');
        $is_unlock = $this->request->param('is_unlock',0,'intval');

        $order = $this->model
            ->where('id', $order_id)
            ->whereIn('status', [1])
            ->find();

        if (empty($order)) {
            $this->error(__('No results were found'));
        }

        //退款
        if ($order['pay_type']=='money'){
//            OrderService::handleCancelOrder($order['order_sn']);
            OrderService::handleCompleteOrder($order['order_sn']);
        }elseif ($order['pay_type']=='wechat'){
//            $refund_order = [
//                'out_trade_no' => $order['order_sn'],
//                'out_refund_no' => strval(time()),
//                'amount' => [
//                    'refund' => intval($order['total_fee']*100),
//                    'total' => intval($order['total_fee']*100),
//                    'currency' => 'CNY',
//                ],
//                '_action' => 'mini', // 小程序退款
//            ];
            $refund_order = [
                'out_trade_no' => $order['order_sn'],
                'out_refund_no' => time(),
                'total_fee' => intval($order['total_fee']*100),
                'refund_fee' => intval($order['total_fee']*100),
                'refund_desc' => '订单退款',
                'type'=>'miniapp'
            ];
            Log::info('退款参数');
            Log::info($refund_order);
            $result = Service::refund($refund_order);
           // $result = \app\admin\model\Order::refund($order);
           //  $result = [
           //      'return_code'=>'SUCCESS'
           //  ];
            if (isset($result['return_code'])){
                if ($result['return_code']=='SUCCESS'){
                    OrderService::handleCompleteOrder($order['order_sn']);
                    $order->refund_result = json_encode($result);
                    $order->save();
                    if(!$is_unlock){
                        $order_ticket = OrderTicket::where(['order_id' => $order_id])->select();
                        if ($order_ticket) {
                            foreach ($order_ticket as $item) {
                                $item->status = 3;
                                $item->save();
                            }
                        }
                    }
                }else{
                    $this->error('退款失败:'.$result['return_code']);
                }
            }else{
                $this->error('退款失败:'.$result['return_msg']);
            }
        }

        $this->success('提交成功','',['order_id'=>$order_id]);
    }
    public function unlockSeat()
    {
        $order_id = $this->request->post('order_id');

        $order = $this->model
            ->where('id', $order_id)
            ->whereIn('status', [2])
            ->find();

        if (empty($order)) {
            $this->error(__('No results were found'));
        }
        Db::startTrans();
        try {
            $order_ticket = OrderTicket::where(['order_id' => $order_id])->select();
            if ($order_ticket) {
                foreach ($order_ticket as $item) {
                    $item->status = 3;
                    $item->save();
                }
            }
            DB::commit();
        } catch (\Exception $e) {
            DB::rollback();
            $this->error($e->getMessage());
        }


        $this->success('操作成功');
    }
}
